package com.siashan.toolkit.sms.core.executor;

import com.siashan.toolkit.sms.core.entity.*;
import com.siashan.toolkit.sms.core.exception.Unisms4jException;
import com.siashan.toolkit.sms.core.exception.Unisms4jInvalidParamException;
import com.siashan.toolkit.sms.core.utils.StringUtils;

import java.util.*;

/**
 * 抽象发送处理
 *
 * @author siashan
 * @since v1.0.1
 */
public abstract class AbstractSmsSendExecutor implements SmsSendExecutor {

    /**
     * 短信配置
     */
    protected final SmsConfig smsConfig;

    /**
     * 短信模板
     */
    protected Map<String, SmsTemplate> templateMap = new HashMap<>();

    /**
     * 白名单
     */
    protected SmsWhiteList whiteList;

    /**
     * 发送频率限制
     */
    public SmsFrequencyLimitConfig frequencyLimit;

    /**
     * 渠道编码
     */
    public String channelCode;

    /**
     * 构造方法
     *
     * @param config 短信配置类
     */
    public AbstractSmsSendExecutor(SmsConfig config) {
        this.smsConfig = config;
    }

    /**
     * 获取渠道编码
     *
     * @return  渠道编码
     */
    @Override
    public String getChannelCode(){
        return channelCode;
    }

    @Override
    public void setChannelCode(String channelCode){
        this.channelCode = channelCode;
    }

    /**
     * 封装短信发送bean
     *
     * @param sendModel  短信发送
     * @param phone  手机号
     * @return  封装后的短信发送bean
     */
    public SmsModel wrapSmsSendModel(SmsModel sendModel, String phone) {
        wrapSmsSendModel(sendModel);
        sendModel.setPhones(Arrays.asList(phone));
        return sendModel;
    }

    /**
     * 封装短信发送bean
     *
     * @param sendModel  短信发送
     * @param phones  手机号
     * @return  封装后的短信发送bean
     */
    public SmsModel wrapSmsSendModel(SmsModel sendModel, Collection<String> phones) {
        wrapSmsSendModel(sendModel);
        sendModel.setPhones(phones);
        return sendModel;
    }

    /**
     * 封装短信发送bean
     *
     * @param sendModel  短信发送
     * @return  封装后的短信发送bean
     */
    public void wrapSmsSendModel(SmsModel sendModel) {
        SmsTemplate smsTemplate = templateMap.get(sendModel.getBizCode());
        if (StringUtils.isBlank(sendModel.getTemplateId())) {
            sendModel.setTemplateId(smsTemplate.getProviderTmplCode());
        }
        if (StringUtils.isBlank(sendModel.getSignName())) {
            sendModel.setSignName(smsTemplate.getSignature());
        }
        if (StringUtils.isBlank(sendModel.getTemplate())) {
            sendModel.setTemplate(smsTemplate.getTmplContent());
        }
    }



    /**
     * 参数转换,只保留参数值
     *
     * @param srcParam     平台参数
     * @param paramMapping 参数映射配置文件
     * @return
     */
    public List<String> transferParamsWithoutKey(Map<String, String> srcParam, String paramMapping) {
        List<String> parmList = new ArrayList<>();
        if (StringUtils.isBlank(paramMapping)) {
            Set<String> keySet = srcParam.keySet();
            Iterator<String> iterator = keySet.iterator();
            while (iterator.hasNext()) {
                parmList.add(srcParam.get(iterator.next()));
            }
        } else {
            String[] mappingArr = paramMapping.split(",");
            for (String mapStr : mappingArr) {
                if (StringUtils.isBlank(mapStr)) {
                    throw new Unisms4jInvalidParamException("参数不合法: paramMapping 字段格式错误！");
                }
                String[] map = mapStr.split(":");
                int len = map.length;
                if (len > 2) {
                    throw new Unisms4jInvalidParamException("参数不合法: paramMapping 字段格式错误！");
                }
                if (len == 2) {
                    parmList.add(srcParam.get(map[1]));
                } else {
                    parmList.add(srcParam.get(map[0]));
                }

            }
        }
        return parmList;
    }


    /**
     * 根据短信验证码请求参数生成NoticeData
     *
     * @param verifyData 验证码请求参数
     *
     * @return NoticeData
     */
    public SmsModel verifyData2NoticeData(SmsVerifyModel verifyData) {
        SmsModel smsSendModel = SmsModel.build(verifyData.getBizCode(), verifyData.getParams());
        wrapSmsSendModel(smsSendModel);
        return smsSendModel;
    }


    @Override
    public SmsFrequencyLimitConfig getFrequencyLimitConfig() {
        return this.frequencyLimit;
    }

    @Override
    public SmsWhiteList getWhiteList(){
        return this.whiteList;
    }

    /**
     * 发送短信验证码
     *
     * @param verifyData 短信验证码内容
     * @param phone  手机号
     * @return 是否发送成功
     */
    @Override
    public boolean send(SmsVerifyModel verifyData, String phone) {
        return send(verifyData2NoticeData(verifyData),phone);
    }


    /**
     * 发送短信验证码
     *
     * @param smsSendModel 短信内容
     * @param  phone  手机号
     * @return 是否发送成功
     */
    @Override
    public boolean send(SmsModel smsSendModel, String phone) {
        if (StringUtils.isBlank(phone)){
            throw new Unisms4jException("短信发送调用失败：手机号不能为空");
        }
        return doSend(wrapSmsSendModel(smsSendModel,phone));
    }

    /**
     * 发送短信验证码
     *
     * @param smsSendModel 短信内容
     * @param  phones  手机号
     * @return 是否发送成功
     */
    @Override
    public boolean send(SmsModel smsSendModel, Collection<String> phones) {
        if (null == phones || phones.isEmpty()){
            throw new Unisms4jException("短信发送调用失败：手机号不能为空");
        }
        return doSend(wrapSmsSendModel(smsSendModel,phones));
    }

    public abstract boolean doSend(SmsModel smsSendModel);
}
